//***************************************************************************//
//*
//* 内容摘要：FEC解码接口
//*	
//* 当前版本：V1.0		
//* 作    者：zhfayuan
//* 完成日期：2016-8-21
//**************************************************************************//
#ifndef CSDFECDEC_H
#define CSDFECDEC_H

#include "SDPacketBufman.h"
#include "SDCommDef.h"
#include "SDFecInterface.h"
#include "SDVanderDec.h"
#include "SDRtp.h"


typedef struct T_FecDecode
{

    T_FEC_DATA      tFecData[MAX_GROUP_SIZE];    //媒体数据缓冲信息结构
    T_FEC_DATA      tFecParity[MAX_GROUP_SIZE];   //校验数据缓冲信息结构

	UINT8           ucHeader_src[MAX_GROUP_SIZE][MAX_HEADER_LEN];
	UINT8           ucHeader_bak[MAX_GROUP_SIZE][MAX_HEADER_LEN];
		
    BOOL            bStartDec;  //是否启动fec 解码，如果不启动，则透传数据到sink插件

    BOOL            bFirstPacket;     //是否是启动FEC解码后收到的第一个包

    BOOL            bLost;                     //是否出现丢包

    BOOL            bRecvFirstPacketOfGroup; //收到组中第一个包

    UINT8           uGroupNo;        
    UINT8           uGroupDataNum;   //一个组中所包含的媒体包个数
    UINT8           uGroupParityNum; //一个组中所包含的校验包个数
    UINT8           uRecvDataNum;    //已经接收到的属于一个组的媒体包个数
    UINT8           uRecvParityNum;  //已经接收到的属于一个组的校验包个数
    UINT8           uLastOutputGroupPos; //上一次输出的媒体包的在组中的位置
    BOOL            bGetBufferForRecovery; //是否已经为丢失的包请求恢复
    BOOL            bSendBufferData;        //是否已经输出丢失的包

    UINT16          usPartyFecHdrLen;  //冗余包中fec头长度
    UINT32          uGroupMaxPacketLen;


}T_FecDecode;


class CSDFecDecProcess
{
public:
	CSDFecDecProcess()
	{
		FecDecode_CreateNew();
	}
	virtual ~CSDFecDecProcess()
	{
		FecDecode_Destroy();
	}
	MD_STATUS FecDecode_Start(void);
	MD_STATUS FecDecode_Stop(void);
	void FecDecode_Enable(bool bEnable = true);
	void FecDecode_setParams(UINT8 eFecParamType, VOID *value);
	void FecDecode_getParams(UINT8 eFecParamType, VOID *value);
	void FecDecode_decode(T_PacketBuffer *pPacketBuffer);
	BOOL FecDecode_groupRecvNotFinish(T_PacketBuffer *pPacketBuffer);
#if ENABLE_NACK
	BOOL FecDecode_cannotRecover(T_PacketBuffer *pPacketBuffer);
	//本端接收丢包且无法恢复，通过NACK信令通道向远端请求IDR
	virtual void pfNeedRemoteSendIdrCallback() {}
#endif

	BOOL GetTranParamsForRemoteFec(UINT8 &byGroupSize, UINT8 &byRedunSize);
private:
	T_FecDecode*	m_pFecDecode;
	CSDVanderDec*	m_pVanderDec;
	unsigned char	m_ucFecWaterMark[MAX_WATERMARK_LEN];
	unsigned int	m_unFecWaterMarkLen;
	UINT8			m_byRedunPacketNumInGroup;
	bool			m_bEnableFecDec;

	void FecDecode_CreateNew(void);
	void FecDecode_Destroy(void);	
	virtual MD_STATUS pfFecDecOutCallback(T_PacketBuffer *pPacketBuffer) = 0;
	virtual T_PacketBuffer *pfGet2KPacketBufCallback(void) = 0;
	void WaterMarkInit(void);
	MD_STATUS FecDecode_InitObject(void);
	void FecDecode_UnInitObject(void);
	void FecDecode_resetGroupInfo(T_MyPayloadInfo *ptMyPayloadInfo);
	void FecDecode_saveData(T_PacketBuffer *pPacketBuffer);
	MD_STATUS FecDecode_GetBufferForRecover(T_PacketBuffer *pPacketBuffer);
	void FecDecode_sendBufferData(void);
	void FecDecode_FreeBuffer(void);
	INT32 FecDecode_parseFecHeader(UINT8 *pBuffer);
	int MDrtpUnpack(char *buf, int len, T_rtpParam *p );
	int FecDecode_GetDataLen(T_PacketBuffer *pPacketBuffer);

};

#endif
